package com.itouchtv.yang.core.eventListener;

import cn.hutool.core.text.csv.CsvRow;
import com.itouchtv.yang.TestCase.webCase.DataMap;
import com.itouchtv.yang.core.MyDictionary;
import com.itouchtv.yang.core.anno.TestFail;
import com.itouchtv.yang.core.anno.TestPass;
import com.itouchtv.yang.core.tools.*;
import org.testng.IAlterSuiteListener;
import org.testng.ISuite;
import org.testng.ISuiteListener;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlInclude;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

public class MySuiteListener implements ISuiteListener, IAlterSuiteListener {
    @Override
    public void onStart(ISuite iSuite) {
        Log.logger.info("启动测试"+iSuite.getXmlSuite().getName());
    }

    @Override
    public void onFinish(ISuite iSuite) {
        Log.logger.info("结束测试"+iSuite.getXmlSuite().getName());
    }

    @Override
    public void alter(List<XmlSuite> list) {
        if (list.get(0).getName().equals("UI自动化测试-cucumber")) return;
        String s = ConfigManager.getProperty("UseDataDriver", "");
        switch (s) {
            case "true":
                MyDictionary.configModule();
                Log.logger.info("UseDataDriver:" + s + "使用数据驱数");
                setSuite2(list);
                break;
            case "false":
                Log.logger.info("UseDataDriver:" + s + "不使用数据驱数");
                break;
            default:
                Log.logger.info("UseDataDriver:" + s + "不使用数据驱数");
                break;
        }

    }

    private void setSuite2(List<XmlSuite> list) {
        List<Map<String,List<CsvRow>>> csvSuites = getTests();
        XmlSuite xmlSuite = list.get(0);
        XmlTest xmlTest;
        List<XmlTest> xmltests = new ArrayList<>();
        Log.logger.info("开始配置testNg.xml...");
        Objects.requireNonNull(csvSuites,"没有找到可用的测试用例");
        for (Map<String,List<CsvRow>> cvsSuite:csvSuites){
            for (Map.Entry<String,List<CsvRow>> test:cvsSuite.entrySet()){
                String name = test.getValue().get(0).getByName("用例描述");
                String driverName = test.getValue().get(0).getByName("browser");
                DataMap.tests.put(name, test.getValue());
                xmlTest = new XmlTest(xmlSuite);
                List<XmlClass> classes = new ArrayList<>();
                XmlClass xmlClass = new XmlClass();
                xmlTest.setName(name);
                xmlClass.setClass(com.itouchtv.yang.TestCase.webCase.DataCase.class);
                classes.add(xmlClass);
                xmlTest.setClasses(classes);
                xmlTest.addParameter("testName", name);
                xmlTest.addParameter("driverName", driverName);
                xmltests.add(xmlTest);
            }

        }
        xmlSuite.setTests(xmltests);
        Log.logger.info("testNg.xml配置完成");
    }

    public static List<Map<String,List<CsvRow>>> getTests() {
        String key = ConfigManager.getProperty("DataDriverFiles", "");
        String path = ClassPath.getClassPath()+"/testCase/";
        List<String> dataDriverFiles;
        if (Objects.equals(key, "")) {
            dataDriverFiles = FileList.getFileList(path,"csv");
        } else dataDriverFiles = Arrays.asList(key.split(","));
        if (Objects.nonNull(dataDriverFiles)){
            List<Map<String,List<CsvRow>>> cvsSuites = new ArrayList<>();
            for (String s:dataDriverFiles){
                cvsSuites.addAll(AnalysisCVS.getDataDriverCsv(path+s));
            }
            return cvsSuites;
        }else return null;
    }

    @Deprecated
    private void setSuite(List<XmlSuite> list) {
        List<List<String[]>> tests = AnalysisCVS.readCVS(ClassPath.getClassPath() + "testCase\\testCase.cvs");
        XmlSuite suite = list.get(0);
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        HashMap<String, String> paramenter = null;
        XmlTest xmlTest;
        Log.logger.info("开始配置测试...");

        for (List<String[]> test : tests) {
            XmlClass xmlcla = null;
            xmlTest = new XmlTest(suite);
            xmlTest.setName(test.get(0)[0]);
            String className = "";
            List<XmlClass> classes = new ArrayList<>();
            List<XmlInclude> xmlIncludes = null;
            for (String[] s : test) {
                XmlInclude xmlInclude = null;
                int i = 0;
                switch (i) {
                    case 0:
                        if (i < s.length - 1) {
                            i++;
                        } else break;
                    case 1:
                        if (!MyDictionary.module.get(s[i]).equals(className)) {
                            xmlcla = null;
                            xmlIncludes = null;
                        }
                        if (xmlcla == null) {
                            xmlcla = new XmlClass();
                            className = MyDictionary.module.get(s[i]);
                            xmlcla.setName(className);
                            classes.add(xmlcla);
                            xmlIncludes = new ArrayList<>();
                        } else {
                            for (XmlClass cl : classes) {
                                if (!cl.getName().equals(xmlcla.getName())) {
                                    xmlcla = new XmlClass();
                                    className = MyDictionary.module.get(s[i]);
                                    xmlcla.setName(className);
                                    classes.add(xmlcla);
                                    xmlIncludes = new ArrayList<>();
                                }
                            }
                        }
                        if (i < s.length - 1) {
                            i++;
                        } else break;
                    case 2:
                        if (i < s.length - 1) {
                            i++;
                        } else break;
                    case 3:
                        String passName = "";
                        String failName = "";
                        String passAnno = TestPass.class.getName();
                        String failAnno = TestFail.class.getName();
                        try {
                            Method[] methods = classLoader.loadClass(className).getMethods();
                            for (Method m : methods) {
                                Annotation[] annotations = m.getAnnotations();
                                for (Annotation annotation : annotations) {
                                    String name = annotation.annotationType().getName();
                                    if (name.equals(passAnno)) {
                                        passName = m.getName();
                                    } else if (name.equals(failAnno)) {
                                        failName = m.getName();
                                    }
                                }
                            }
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                        if (s[i].equals("成功") && !passName.equals("")) {
                            xmlInclude = new XmlInclude(passName);
                            xmlIncludes.add(xmlInclude);
                        } else if (s[i].equals("失败") && !failName.equals("")) {
                            xmlInclude = new XmlInclude(failName);
                            xmlIncludes.add(xmlInclude);
                        }
                        if (i < s.length - 1) {
                            i++;
                        } else break;
                    case 4:
                        paramenter = new HashMap<>();
                        if (xmlInclude == null && s[i].equals("")) {
                            paramenter.put("dataFile", s[i]);
                        }
                        if (xmlInclude != null && s[i].equals("")) {
                            paramenter.put("dataFile", s[i]);
                            xmlInclude.setParameters(paramenter);
                            paramenter = null;
                        }
                        break;
                }
                if (xmlIncludes.size() != 0) {
                    xmlcla.setIncludedMethods(xmlIncludes);
                }
            }
            if (xmlcla.getIncludedMethods().size() == 0 && paramenter != null) {
                xmlcla.setExcludedMethods(new ArrayList<>());
                xmlcla.setParameters(paramenter);
                paramenter = null;
            }
            xmlTest.setXmlClasses(classes);
        }
        Log.logger.info("测试配置完成");
        for (XmlTest t : suite.getTests()) {
            System.out.println("Test:" + t.getName());
            for (XmlClass xc : t.getClasses()) {
                System.out.println("  " + "class:" + xc.getName());
                for (XmlInclude xi : xc.getIncludedMethods()) {
                    System.out.println("    method:" + xi.getName());
                    System.out.println("    parameters:" + xi.getLocalParameters());
                }
                for (String s : xc.getExcludedMethods()) {
                    System.out.println("    method:" + s);
                }
            }
        }
    }
}
